package com.wangsong.system.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wangsong.common.model.CodeEnum;
import com.wangsong.common.model.GetEasyUIData;
import com.wangsong.system.entity.Role;
import com.wangsong.system.entity.RoleResources;
import com.wangsong.system.entity.User;
import com.wangsong.system.entity.UserRole;
import com.wangsong.system.mapper.RoleMapper;
import com.wangsong.system.mapstruct.RoleMapstruct;
import com.wangsong.system.service.IResourcesService;
import com.wangsong.system.service.IRoleResourcesService;
import com.wangsong.system.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangsong.system.service.IUserRoleService;
import com.wangsong.system.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2021-09-19
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    @Autowired
    private IResourcesService resourcesService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private RoleMapstruct roleMapstruct;
    @Override
    @Transactional
    public void insertRole(RoleAddVO role) {
        Long[] resourcesIds = role.getResourcesId();

        save(role);
        resourcesService.saveBatchroleResources(resourcesIds, role);
    }


    @Override
    @Transactional
    public void updateRole(RoleUpdateVO role) {
        Long[] resourcesIds = role.getResourcesId();


        updateById(role);

        resourcesService.removeRoleResource(role);
        resourcesService.saveBatchroleResources(resourcesIds, role);
    }

    @Override
    public void deleteRole(Long[] id) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.in("role_id", id);
        userRoleService.remove(updateWrapper);
        resourcesService.removeRoleResources(id);
        removeByIds(ListUtil.toList(id));
    }

    @Override
    public GetEasyUIData findTByPage(RolePageVO role) {
        IPage<Role> page = new Page<>(role.getPage(), role.getRows());
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(StrUtil.isNotBlank(role.getName()), "name", role.getName());
        IPage<Role> page1 = page(page, queryWrapper);
        return new GetEasyUIData(page1.getRecords(), page1.getTotal());

    }

    @Override
    public RoleVO selectByPrimaryKey(Long id) {
        Role role = getById(id);

        RoleVO roleVO = roleMapstruct.toVO(role);
        List<RoleResources> roleResourcesList = resourcesService.listRoleResources(id);
        roleVO.setRoleResourcesList(roleResourcesList);
        return roleVO;
    }

    @Override
    public void saveBatch(Long[] roleIds, User user) {
        List<UserRole> userRoleList = Arrays.stream(roleIds)
                .map(roleId -> getUserRole(user, roleId))
                .collect(Collectors.toList());
        userRoleService.saveBatch(userRoleList);
    }

    private static UserRole getUserRole(User user, Long roleId) {
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(roleId);
        return userRole;
    }

    @Override
    public void removeUserRole(UserUpdateVO user) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("user_id", user.getId());
        userRoleService.remove(updateWrapper);
    }

    @Override
    public void removeUserRoles(Long[] ids) {
        UpdateWrapper deleteWrapper = new UpdateWrapper();
        deleteWrapper.in("user_id", ids);
        userRoleService.remove(deleteWrapper);
    }

    @Override
    public List<UserRole> list(Long userId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", userId);
        List<UserRole> userRoleList = userRoleService.list(queryWrapper);
        return userRoleList;
    }
}
